﻿using gregn6Lib;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Gridpp6
{
    /// <summary>
    /// 处理报表与类之间的数据交互
    /// </summary>
    public class ReportDealClass<T> where T : class
    {
        //存放报表字段
        private Dictionary<string, IGRField> dicFieldList = null;
        //private Dictionary<string, IGRParameter> dicParameterList = null;
        //区分固定实体字段和参数
        private ArrayList arrayParameters = null;
        private ArrayList arrayFields = null;
        //区分动态实体字段和参数
        private ArrayList arrayDynParameters = null;
        private ArrayList arrayDynFields = null;

        private List<T> DataModel { get; set; }
        private GridppReport Report { get; set; }

        /// <summary>
        /// 传入列表数据 动态类型T传dynamic
        /// </summary>
        /// <param name="dm">列表数据</param>
        /// <param name="reportFile">打印模板地址</param>
        /// <param name="printerName">打印机名称</param>
        public ReportDealClass(List<T> dm, string reportFile, string printerName)
        {
            this.DataModel = dm;

            InitReport(reportFile, printerName);
            InitData();
        }

        /// <summary>
        /// 传入单条数据 动态类型T传dynamic
        /// </summary>
        /// <param name="dm">单条数据</param>
        /// <param name="reportFile">打印模板地址</param>
        /// <param name="printerName">打印机名称</param>
        public ReportDealClass(T dm, string reportFile, string printerName)
        {
            List<T> temp = new List<T>();
            temp.Add(dm);
            this.DataModel = temp;

            InitReport(reportFile, printerName);
            InitData();
        }

        void InitReport(string reportFile, string printerName)
        {
            this.Report = new GridppReport();
            Report.LoadFromFile(reportFile);

            //设置打印机，未设置则按默认打印机
            if (!string.IsNullOrWhiteSpace(printerName))
                Report.Printer.PrinterName = printerName;
        }

        void InitData()
        {
            //区别报表的参数和字段
            arrayFields = new ArrayList();
            arrayParameters = new ArrayList();
            //动态类型
            arrayDynFields = new ArrayList();
            arrayDynParameters = new ArrayList();

            //获取T中的属性值
            var type = typeof(T);
            if (type.Name.ToLower() == "object")  //传过来的是dynamic类型
            {
                var list = DataModel as dynamic;
                foreach (KeyValuePair<string, object> col in list[0])
                {
                    string propName = col.Key;//属性
                    var field = this.Report.FieldByName(propName);
                    if (field != null)
                    {
                        arrayDynFields.Add(propName);
                    }
                    else
                    {
                        arrayDynParameters.Add(propName);
                    }
                }
            }
            else  //已知确定的实体
            {
                PropertyInfo[] propList = typeof(T).GetProperties();
                if (propList.Length > 0)
                {
                    foreach (PropertyInfo item in propList)
                    {
                        string propName = item.Name;
                        var field = this.Report.FieldByName(propName);
                        if (field != null)
                        {
                            arrayFields.Add(propName);
                        }
                        else
                        {
                            arrayParameters.Add(propName);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 填充字段数据
        /// </summary>
        void Report_FetchRecord()
        {
            //循环加载数据
            if (typeof(T).Name.ToLower() == "object")  //传过来的是dynamic类型
            {
                var list = DataModel as dynamic;
                foreach (T item in list)
                {
                    Report.DetailGrid.Recordset.Append();
                    FillRecord(item);
                    Report.DetailGrid.Recordset.Post();
                }
            }
            else
            {
                foreach (T item in DataModel)
                {
                    Report.DetailGrid.Recordset.Append();
                    FillRecord(item);
                    Report.DetailGrid.Recordset.Post();
                }
            }
        }

        private void FillRecord(T model)
        {
            foreach (string fieldName in arrayFields)
            {
                IGRField currentField = dicFieldList[fieldName];
                object fieldValue = typeof(T).GetProperty(fieldName).GetValue(model, null);
                currentField.AsString = fieldValue != null ? fieldValue.ToString() : "";
            }
            foreach (string fieldName in arrayDynFields)
            {
                var item = model as dynamic;
                string val = string.Empty;
                foreach (KeyValuePair<string, object> col in item)
                {
                    if (col.Key == fieldName)
                    {
                        val = col.Value == null ? string.Empty : col.Value.ToString();
                        break;
                    }
                }
                IGRField currentField = dicFieldList[fieldName];
                currentField.AsString = val;
            }

            //foreach (string ParameterName in arrayParameters)
            //{
            //    IGRParameter currentParameter = dicParameterList[ParameterName];
            //    object ParameterValue = typeof(T).GetProperty(ParameterName).GetValue(model, null);
            //    currentParameter.AsString = ParameterValue != null ? ParameterValue.ToString() : "";
            //}
        }

        /// <summary>
        /// 报表初始化
        /// </summary>
        void Report_Initialize()
        {
            //初始化字段
            dicFieldList = new Dictionary<string, IGRField>();
            foreach (string field in arrayFields)
            {
                IGRField reportField = Report.FieldByName(field);
                dicFieldList.Add(field, reportField);
            }
            //初始化动态类型字段
            foreach (string field in arrayDynFields)
            {
                IGRField reportField = Report.FieldByName(field);
                dicFieldList.Add(field, reportField);
            }

            //dicParameterList = new Dictionary<string, IGRParameter>();
            //foreach (string Parameter in arrayParameters)
            //{
            //    IGRParameter reportParameter = Report.ParameterByName(Parameter);
            //    dicParameterList.Add(Parameter, reportParameter);
            //}
        }

        /// <summary>
        /// 报表打印
        /// </summary>
        /// <param name="isPreview">是否打印预览 默认false</param>
        /// <param name="showPrintDialog">是否显示打印对话框（非预览时有效） 默认false</param>
        public bool ReportPrint(bool isPreview = false, bool showPrintDialog = false)
        {
            bool ret = false;
            if (DataModel.Count <= 0 || Report == null)
            {
                return ret;
            }

            try
            {
                //添加处理委托
                Report.Initialize += new _IGridppReportEvents_InitializeEventHandler(Report_Initialize);
                Report.FetchRecord += new _IGridppReportEvents_FetchRecordEventHandler(Report_FetchRecord);

                //处理参数内容的填充
                T firstData = DataModel[0];
                Type typeT = typeof(T);
                foreach (string parameter in arrayParameters)
                {
                    object value = typeT.GetProperty(parameter).GetValue(firstData, null);
                    var para = Report.ParameterByName(parameter);
                    if (para != null)
                    {
                        para.AsString = value == null ? "" : value.ToString();
                    }
                }

                foreach (string parameter in arrayDynParameters)
                {
                    var item = firstData as dynamic;
                    string val = string.Empty;
                    foreach (KeyValuePair<string, object> col in item)
                    {
                        if (col.Key == parameter)
                        {
                            val = col.Value == null ? string.Empty : col.Value.ToString();
                            break;
                        }
                    }
                    var para = Report.ParameterByName(parameter);
                    if (para != null)
                    {
                        para.AsString = val;
                    }
                }

                if (isPreview)
                {
                    Report.PrintPreview(false);
                }
                else
                {
                    Report.Print(showPrintDialog);
                }

                Report.Initialize -= new _IGridppReportEvents_InitializeEventHandler(Report_Initialize);
                Report.FetchRecord -= new _IGridppReportEvents_FetchRecordEventHandler(Report_FetchRecord);

                ret = true;
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return ret;
        }

    }

}
